/**
 * SUNING APPLIANCE CHAINS.
 * Copyright (c) 2012-2012 All Rights Reserved.
 */
package com.suning.sawp.in.controller;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.text.MessageFormat;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.suning.sawp.constants.ErrorCodeConstants;
import com.suning.sawp.dto.common.ReturnMsg;
import com.suning.sawp.exception.SawpException;
import com.suning.sawp.service.util.BaseContants;


@Controller
public class DjBaseController extends
		com.suning.framework.web.controller.BaseController {
	private static final Logger LOGGER = LoggerFactory
			.getLogger(DjBaseController.class);

	private static final String CHAR_SET = "utf-8";

	public static final String TIMESTYLE = "yyyy-MM-dd HH:mm:ss.SSS";
	
	private static final Integer PAGE_ONE = 1;
	private static final Integer PAGE_TEN = 10;
	private static final String SYSTEM_EXCEPTION = "SE";
    private static final String BUSINESS_EXCEPTION = "BE";

	/**
	 * 
	 * 功能描述：获取请求参数
	 * 
	 * @param key
	 * @return 返回值
	 * @throw 异常描述
	 * @see 需要参见的其它内容
	 */
	protected String getParam(String key, HttpServletRequest request) {
		return request.getParameter(key);
	}

	/**
	 * 根据名字获取cookie
	 * 
	 * @param request
	 * @param key
	 *            cookie名字
	 * @return
	 */
	protected String getCookie(HttpServletRequest request, String key) {
		Map<String, Cookie> cookieMap = readCookieMap(request);
		if (cookieMap.containsKey(key)) {
			Cookie cookie = (Cookie) cookieMap.get(key);
			return cookie.getValue();
		} else {
			return null;
		}
	}

	/**
	 * 将cookie封装到Map里面
	 * 
	 * @param request
	 * @return
	 */
	private static Map<String, Cookie> readCookieMap(HttpServletRequest request) {
		Map<String, Cookie> cookieMap = new HashMap<String, Cookie>();
		Cookie[] cookies = request.getCookies();
		if (null != cookies) {
			for (Cookie cookie : cookies) {
				cookieMap.put(cookie.getName(), cookie);
			}
		}
		return cookieMap;
	}

	/**
	 * 对象转换成json
	 */
	protected String getJson(Object oj) {
		return gson.toJson(oj);
	}

	/**
	 * 
	 * 功能描述:将json数据写入响应头
	 * 
	 * @param obj
	 * @param response
	 * @see [相关类/方法](可选)
	 * @since [产品/模块版本](可选)
	 */
	protected void writeJsonToResponse(Object obj, HttpServletResponse response) {
		response.setCharacterEncoding(CHAR_SET);
		response.setHeader("Content-Language", "zh-CN");
		response.setContentType("application/json;charset=" + CHAR_SET);

		Gson gson = new GsonBuilder().disableHtmlEscaping().create();

		try {
			response.getOutputStream().print(gson.toJson(obj));
			response.getOutputStream().flush();
		} catch (UnsupportedEncodingException e) {
			LOGGER.error("writeJsonToResponse is error", e);
		} catch (IllegalStateException e2) {
			LOGGER.error("writeJsonToResponse is error", e2);
		} catch (IOException e3) {
			LOGGER.error("writeJsonToResponse is error", e3);
		}
	}

	/**
	 * 创建新的GsonView返回对象，并填充默认值
	 * 
	 * @return GsonView对象
	 */
	public MyGsonView createGsonView() {
	    MyGsonView gsonView = new MyGsonView();
		gsonView.addStaticAttribute(BaseContants.RET_FLAG, BaseContants.SUCCESS);
		gsonView.addStaticAttribute(BaseContants.ERROR_CODE, StringUtils.EMPTY);
		gsonView.addStaticAttribute(BaseContants.ERROR_MSG, StringUtils.EMPTY);
		return gsonView;
	}

	/**
	 * 
	 * 功能描述: <br>
	 * 获取请求参数
	 * 
	 * @param key
	 * @param request
	 * @return
	 * @see [相关类/方法](可选)
	 * @since [产品/模块版本](可选)
	 */
	protected String getParameter(String key, HttpServletRequest request) {
		if ("".equalsIgnoreCase(key) || key == null) {
			return null;
		} else {
			return request.getParameter(key);
		}
	}

	protected Map<String, String> typeConvert(Map<?, ?> rawMap) {
		Map<String, String> paramMap = new HashMap<String, String>();

		for (Map.Entry<?, ?> entry : rawMap.entrySet()) {
			Object key = entry.getKey();
			Object value = entry.getValue();
			if (key instanceof String && value instanceof String[]) {
				paramMap.put((String) key, ((String[]) value)[0]);
			}
		}
		return paramMap;
	}
	
	/**
     * 设置错误码，错误描述
     * @param view
     * @param errorCode
     */
    protected void setErrorMsg (MyGsonView view, String errorCode) {
        if (null != view && StringUtils.isNotBlank(errorCode)) {
            view.addStaticAttribute(BaseContants.RET_FLAG,
                    BaseContants.FAILED);
            view.addStaticAttribute(BaseContants.ERROR_CODE, errorCode);
            view.addStaticAttribute(BaseContants.ERROR_MSG, ErrorCodeConstants.ERR_MAP.get(errorCode));
        }
    }
    
    /**
     * 
     * 功能描述: 展示结果赋值<br>
     * 〈功能详细描述〉
     * @param <T>
     *
     * @param view
     * @param retMsg
     * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)
     */
    protected <T> MyGsonView setGsonView (ReturnMsg<T> retMsg) {
        MyGsonView view = new MyGsonView();
        if (ReturnMsg.FAIL.equals(retMsg.getRetFlag())) {
            // 失败塞入相对应的错误码和错误信息
            view.addStaticAttribute(BaseContants.ERROR_CODE, retMsg.getErrorCode());
            view.addStaticAttribute(BaseContants.ERROR_MSG, retMsg.getErrorMessage());
        }
        view.addStaticAttribute(BaseContants.RET_FLAG, retMsg.getRetFlag());
        view.addStaticAttribute(BaseContants.DATA, retMsg.getData());
        
        return view;
    }
    
    /**
     * 设置错误码，错误描述
     * @param view
     * @param errorCode
     * @param keys 多参数
     */
    protected void setErrorMsg (MyGsonView view, String errorCode, Object... keys) {
        if (null != view && StringUtils.isNotBlank(errorCode)) {
            if (null == keys) {
                setErrorMsg(view, errorCode);
            } else {
                view.addStaticAttribute(BaseContants.RET_FLAG,
                        BaseContants.FAILED);
                view.addStaticAttribute(BaseContants.ERROR_CODE, errorCode);
                MessageFormat form = new MessageFormat(ErrorCodeConstants.ERR_MAP.get(errorCode));
                view.addStaticAttribute(BaseContants.ERROR_MSG, form.format(keys));
            }
        }
    }
    
    protected Map<String, Integer> getPageParams(Integer pageNo, Integer pageSize) {
       Map<String, Integer> pageParams = new HashMap<String, Integer>();
       pageNo = null == pageNo ? PAGE_ONE : pageNo;
       pageSize = (null == pageSize || pageSize > PAGE_TEN) ? PAGE_TEN : pageSize;
       pageParams.put("start", (pageNo - 1) * pageSize);
       pageParams.put("end", pageSize);
       return pageParams;
    }
   
    /**
     * 业务异常统一处理
     * 
     * @param ex
     * @return
     */
    @ExceptionHandler(SawpException.class)
    @ResponseBody
    public MyGsonView simpExceptionHandle(Exception ex) {
        MyGsonView view = new MyGsonView();
        view.addStaticAttribute(BaseContants.RET_FLAG, BaseContants.FAILED);
        view.addStaticAttribute(BaseContants.ERROR_CODE, BUSINESS_EXCEPTION);
        view.addStaticAttribute(BaseContants.ERROR_MSG, ex.getMessage());
        LOGGER.warn(ex.getMessage());
        return view;
    }
    
    /**
     * 系统异常统一处理
     * 
     * @param ex
     * @return
     */
    @ExceptionHandler(Exception.class)
    @ResponseBody
    @ResponseStatus(value = HttpStatus.INTERNAL_SERVER_ERROR)
    public MyGsonView exceptionHandle(Exception ex) {
        MyGsonView view = new MyGsonView();
        view.addStaticAttribute(BaseContants.RET_FLAG, BaseContants.FAILED);
        view.addStaticAttribute(BaseContants.ERROR_CODE, SYSTEM_EXCEPTION);
        view.addStaticAttribute(BaseContants.ERROR_MSG, ex.getMessage());
        LOGGER.error("occur exception：", ex);
        return view;
    }

}
